package itd.db;
import java.sql.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;

public class DBPool {
	private static Hashtable connections = null;
	private static Properties props;

	public DBPool(Properties props, int initialConnections)
			throws SQLException, ClassNotFoundException {
		DBPool.props = props;
		initializePool(props, initialConnections);
	}

	public DBPool(String driverClassName, String dbURL, String user,
			String password, int initialConnections) throws SQLException,
			ClassNotFoundException {
		props = new Properties();
		props.put("connection.driver", driverClassName);
		props.put("connection.url", dbURL);
		props.put("user", user);
		props.put("password", password);
		initializePool(props, initialConnections);
	}
	
	public static void initConnections(String driverClassName, String dbURL, String user,
			String password, int initialConnections) throws SQLException, ClassNotFoundException {
		props = new Properties();
		props.put("connection.driver", driverClassName);
		props.put("connection.url", dbURL);
		props.put("user", user);
		props.put("password", password);
		initializePool(props, initialConnections);
	}

	public static Connection getConnection() throws Exception {
		Connection con = null;

		if (connections == null) {
			connections = new Hashtable();
			initConnections("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/comparator", "root", "root", 10);
		//	initConnections("com.mysql.jdbc.Driver", "jdbc:mysql://localhost.localdomain/itg", "root", "root", 10);
		}

		Enumeration cons = connections.keys();

		synchronized (connections) {
			while (cons.hasMoreElements()) {
				con = (Connection) cons.nextElement();

				Boolean b = (Boolean) connections.get(con);
				if (b == Boolean.FALSE) {
					// So we found an unused connection.
					// Test its integrity with a quick setAutoCommit(true) call.
					// For production use, more testing should be performed,
					// such as executing a simple query.
					try {
						con.setAutoCommit(true);
					} catch (SQLException e) {
						// Problem with the connection, replace it.
						connections.remove(con);
						con = getNewConnection();
					}
					// Update the Hashtable to show this one's taken
					connections.put(con, Boolean.TRUE);
					// Return the connection
					return con;
				}
			}

			// If we get here, there were no free connections. Make one more.
			// A more robust connection pool would have a maximum size limit,
			// and would reclaim connections after some timeout period
			con = getNewConnection();
			connections.put(con, Boolean.FALSE);
			return con;
		}
	}

	public static void returnConnection(Connection returned) {
		if (connections.containsKey(returned)) {
			connections.put(returned, Boolean.FALSE);
		}
	}

	private static void initializePool(Properties props, int initialConnections)
			throws SQLException, ClassNotFoundException {
		// Load the driver
		Class.forName(props.getProperty("connection.driver"));

		// Put our pool of Connections in the Hashtable
		// The FALSE value indicates they're unused
		for (int i = 0; i < initialConnections; i++) {
			Connection con = getNewConnection();
			connections.put(con, Boolean.FALSE);
		}
	}

	private static Connection getNewConnection() throws SQLException {
		return DriverManager.getConnection(props.getProperty("connection.url"), props);
	}
}
